<?php


class SelectServer
{
    public $onConnect = null;
    public $onMessage = null;
    protected $socket = null;
//    protected $workerNum = 4;

    protected $allSocket = [];

    public function __construct(string $address)
    {
        $this->socket = stream_socket_server($address);

        //设置为非堵塞
        stream_set_blocking($this->socket, 0);

        //保存服务端socket，用于判断socket的类型
        $this->allSocket[(int)$this->socket] = $this->socket;
    }

    public function start()
    {
        while (true) { 

            $write = $except = [];

            //需要监听socket
            $read = $this->allSocket;

            stream_select($read, $write, $except, 60);

            //怎么区分服务端和客户端
            foreach ($read as $index => $val) {
                var_dump($read);
                //当前发生改变的是服务端，有连接进入
                if ($val === $this->socket) {
                    $clientSocket = stream_socket_accept($this->socket);//堵塞监听
                    $this->allSocket[(int)$clientSocket] = $clientSocket;
                    if ($clientSocket && is_callable($this->onConnect)) {
                        call_user_func($this->onConnect, $clientSocket);
                    }
                } else {
                    //从连接中读取客户端的内容
                    $data = fread($this->socket, 65535);

                    if (empty($data)) {
                        if (feof($val) || !is_resource($data)) {
                            fclose($val);
                            unset($this->allSocket[(int)$val]);
                            continue;
                        }
                    }

                    //正常读取到数据，出发消息接收事件
                    if (!empty($data) && is_callable($this->onMessage)) {
                        call_user_func($this->onMessage, $data);
                    }
                }
            }

        }
    }
}

$server = new SelectServer('tcp://0.0.0.0:9800');

$server->onConnect = function ($fd) {
//    echo '有连接进来' . (int)$fd;
};

$server->onMessage = function ($fd, $data) {
    echo '有消息进来' . $data;
};

$server->start();